home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / www / src / midaswww-1.0 / midasconvert.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-16  |  11.8 KB  |  442 lines

  1. #include <Mrm/MrmAppl.h>                        /* Motif Toolkit and MRM */
  2. #include "midaslist.h"
  3. #include "midaserrors.h"
  4. #include "midasoperand.h"
  5. #include "midasconvert.h"
  6. #include <X11/cursorfont.h>
  7. #include <X11/CoreP.h>
  8. #include <stdlib.h>
  9.  
  10. static List ConverterList;
  11. static List MidasClassList;
  12. Widget MidasGetActiveWidget();
  13.  
  14. ConvertBlock *MidasFindStringConverter(Type)
  15. MidasType Type;
  16. {
  17.     ListItem *item;
  18.     char buffer[256];
  19.     strcpy(buffer,MString);
  20.     strcat(buffer,".");
  21.     strcat(buffer,Type);
  22.     item = MidasFindItemInList(&ConverterList,buffer);
  23.     if (item == 0) MidasError("Could not find converter for %s to %s",MString,Type);
  24.     return item->Pointer;
  25. }
  26. void MidasDeclareConverter(FromType,ToType,ConvertRtn)
  27.      MidasType FromType;
  28.      MidasType ToType;
  29.      Boolean (*ConvertRtn)();
  30. {
  31.      char *name = XtMalloc(strlen(FromType)+strlen(ToType)+2);
  32.      ListItem *item;
  33.  
  34.      strcpy(name,FromType);
  35.      strcat(name,".");
  36.      strcat(name,ToType);
  37.      item = MidasFindItemInList(&ConverterList,name);
  38.      if (item != 0) 
  39.        {
  40.          XtFree(name);
  41.          MidasError("Duplicate converter for %s to %s ignored",FromType,ToType);
  42.        }
  43.      else
  44.        {
  45.          ConvertBlock *ab = XtNew(ConvertBlock);
  46.          item = MidasAddItemToList(&ConverterList,name);
  47.          item->Pointer = ab;
  48.          ab->ConvertRtn = ConvertRtn;
  49.          ab->FromType = FromType;
  50.          ab->ToType = ToType;
  51.        }
  52.      XtFree(name);
  53. }
  54. void MidasDeclareStringConverter(ToType,ConvertRtn)
  55.      MidasType ToType;
  56.      Boolean (*ConvertRtn)();
  57. {
  58.      MidasDeclareConverter(MString,ToType,ConvertRtn);
  59. }
  60. Boolean MidasConvertOperandInternal(Operand,Type)
  61. MidasOperand *Operand;
  62. MidasType Type;
  63. {
  64.   MidasOperand Temp;
  65.   char name[256];
  66.   ListItem *item;
  67.   ConvertBlock *cb;
  68.   Boolean ok;
  69.    
  70.   if (strcmp(Operand->Type,Type) == 0) return TRUE;
  71.   
  72.   if (strcmp(Type,"any") == 0)
  73.     {
  74.       MidasOperand *new = XtNew(MidasOperand);
  75.       *new = *Operand;
  76.       Operand->Type = "any";
  77.       Operand->Dynamic = TRUE;
  78.       Operand->Value.P = (XtPointer) new;
  79.       return TRUE; 
  80.     }
  81.  
  82.   strcpy(name,Operand->Type);
  83.   strcat(name,".");
  84.   strcat(name,Type);
  85.   item = MidasFindItemInList(&ConverterList,name);
  86.  
  87.   if (item == 0) 
  88.     {
  89.       /*
  90.        * Maybe the intrinsics can do the job for us?
  91.        *
  92.        */
  93.  
  94.       XrmValue from, to;
  95.       Widget ActiveWidget = MidasGetActiveWidget();
  96.       int result;
  97.  
  98.       if (strcmp(Operand->Type,MString) == 0) 
  99.         {
  100.           from.size = strlen(Operand->Value.P) + 1;
  101.           from.addr = Operand->Value.P;
  102.         }
  103.       else
  104.         {
  105.           from.size = sizeof(Operand->Value.P);
  106.           from.addr = Operand->Value.P;
  107.         }
  108.       to.addr = (XtPointer) &result;
  109.       to.size = sizeof(result);
  110.  
  111.       MidasSuppressXtWarningMessages();
  112.  
  113.       ok = XtConvertAndStore(ActiveWidget,Operand->Type,&from,Type,&to);
  114.  
  115.       MidasReenableXtWarningMessages();
  116.  
  117.       if (ok) 
  118.         { 
  119.           if (to.size == sizeof(result)) Operand->Value.I = result;
  120.           else 
  121.             {
  122.               short s;
  123.               memcpy(&s,to.addr,to.size);
  124.               Operand->Value.I = s;
  125.             }
  126.         }
  127.       else if (to.size>sizeof(result))
  128.         {
  129.           to.addr = XtMalloc(to.size);
  130.           ok = XtConvertAndStore(ActiveWidget,Operand->Type,&from,Type,&to);
  131.           
  132.           Operand->Value.P = to.addr;
  133.           Operand->Dynamic = TRUE;
  134.         }
  135.       if (ok) 
  136.         {
  137.           Operand->Type = Type;
  138.           return ok;
  139.         }
  140.  
  141.       if (strcmp(Type,MString) == 0)
  142.         {
  143.           char *p = XtMalloc(12);
  144.           sprintf(p,"%d",Operand->Value.I);
  145.  
  146.           if (Operand->Dynamic) XtFree(Operand->Value.P);
  147.           Operand->Value.P = p;
  148.           Operand->Dynamic = TRUE;
  149.           Operand->Type = MString;
  150.           return TRUE;
  151.         }
  152.       MidasError("No converter declared for %s to %s",Operand->Type,Type);
  153.     }
  154.  
  155.   cb = item->Pointer;
  156.     
  157.   Temp.Dynamic = FALSE;
  158.   Temp.Type = Type;
  159.  
  160.   ok = cb->ConvertRtn(Operand,&Temp);
  161.    
  162.   if (ok)
  163.     {
  164.       if (Operand->Dynamic) XtFree(Operand->Value.P);
  165.       *Operand = Temp; 
  166.     }
  167.  
  168.   return ok;
  169. }
  170. void MidasConvertOperand(Operand,Type)
  171. MidasOperand *Operand;
  172. MidasType Type;
  173. {
  174.   Boolean ok = MidasConvertOperandInternal(Operand, Type);
  175.   if (ok) return;
  176.  
  177.   /* Try to report error as best we can */
  178.  
  179.   if (strcmp(Operand->Type,MString) == 0) 
  180.     MidasError("Can not convert %s from %s to %s",Operand->Value.P,Operand->Type,Type);
  181.  
  182.   else if (strcmp(Type,MString) == 0)
  183.     MidasError("Can not convert operand from %s to %s",Operand->Type,Type);
  184.  
  185.   else
  186.     {
  187.       ok = MidasConvertOperandInternal(Operand, MString);
  188.       if (ok) 
  189.         MidasError("Can not convert %s from %s to %s",Operand->Value.P,Operand->Type,Type);
  190.       else
  191.         MidasError("Can not convert operand from %s to %s",Operand->Type,Type);
  192.     }
  193. }
  194. static MidasOperand MidasConvertForce(Operand,Type)
  195. MidasOperand *Operand;
  196. char *Type;
  197. {
  198.    MidasOperand Temp;
  199.    Temp = *Operand;
  200.    MidasConvertOperand(&Temp,XtNewString(Type)); /* bug ... never freed */
  201.    return Temp; 
  202. }
  203. static Boolean MidasConvertBooleanString(In,Out)
  204. MidasOperand *In;
  205. MidasOperand *Out;
  206. {
  207.    if (In->Value.I) Out->Value.P = "True";
  208.    else             Out->Value.P = "False";
  209.    return TRUE;
  210. }
  211. static Boolean MidasConvertIntString(In,Out)
  212. MidasOperand *In;
  213. MidasOperand *Out;
  214. {
  215.    char *new = XtMalloc(12);
  216.    sprintf(new,"%d",In->Value.P);
  217.    Out->Value.P = new;
  218.    return TRUE;
  219. }
  220. static Boolean MidasConvertFloatString(In,Out)
  221. MidasOperand *In;
  222. MidasOperand *Out;
  223. {
  224.    char *new = XtMalloc(20);
  225.    sprintf(new,"%f",In->Value.F);
  226.    Out->Value.P = new;
  227.    return TRUE;
  228. }
  229. static Boolean MidasConvertStringBoolean(In,Out)
  230. MidasOperand *In;
  231. MidasOperand *Out;
  232. {
  233.   if      (strcmp(In->Value.P,"True" ) == 0) Out->Value.I = TRUE; 
  234.   else if (strcmp(In->Value.P,"true" ) == 0) Out->Value.I = TRUE;
  235.   else if (strcmp(In->Value.P,"TRUE" ) == 0) Out->Value.I = TRUE;
  236.   else if (strcmp(In->Value.P,"False") == 0) Out->Value.I = FALSE;
  237.   else if (strcmp(In->Value.P,"false") == 0) Out->Value.I = FALSE;
  238.   else if (strcmp(In->Value.P,"FALSE") == 0) Out->Value.I = FALSE;
  239.   else return FALSE;
  240.  
  241.   return TRUE;
  242. }
  243. static Boolean MidasConvertStringXmString(In,Out)
  244. MidasOperand *In;
  245. MidasOperand *Out;
  246. {
  247.    Out->Value.P = (XtPointer) MidasCharToString(In->Value.P);
  248.    Out->Dynamic = TRUE; /* Need special destructor for this ??? */
  249.    return TRUE;
  250. }
  251. static Boolean MidasConvertStringUpperName(In,Out)
  252. MidasOperand *In;
  253. MidasOperand *Out;
  254. {
  255.    char *p = In->Value.P;
  256.  
  257.    for (; *p != '\0'; p++) *p = toupper(*p);
  258.  
  259.    Out->Value.P = In->Value.P;
  260.    Out->Dynamic = In->Dynamic;
  261.    In->Dynamic = FALSE;
  262.    return TRUE;
  263. }
  264. static Boolean MidasConvertStringName(In,Out)
  265. MidasOperand *In;
  266. MidasOperand *Out;
  267. {
  268.    Out->Value.P = In->Value.P;
  269.    Out->Dynamic = In->Dynamic;
  270.    In->Dynamic = FALSE;
  271.    return TRUE;
  272. }
  273. static Boolean MidasConvertStringInt(In,Out)
  274. MidasOperand *In;
  275. MidasOperand *Out;
  276. {
  277.    char *End;
  278.  
  279.    Out->Value.P = (XtPointer) strtol((char *)In->Value.P,&End,10);
  280.    return (*End == '\0');
  281. }
  282. static Boolean MidasConvertStringFloat(In,Out)
  283. MidasOperand *In;
  284. MidasOperand *Out;
  285. {
  286.    char *End;
  287.  
  288.    Out->Value.F = strtod(In->Value.P,&End);
  289.    return (*End == '\0');
  290. }
  291. static Boolean MidasConvertStringWidget(In,Out)
  292. MidasOperand *In;
  293. MidasOperand *Out;
  294. {
  295.    Out->Value.P = (XtPointer) MidasFindWidget(In->Value.P);
  296.    return TRUE;
  297. }
  298. static Boolean MidasConvertStringIcon(In,Out)
  299. MidasOperand *In;
  300. MidasOperand *Out;
  301. {
  302.    Out->Value.P = (XtPointer) MidasFetchIcon(In->Value.P);
  303.    return TRUE;
  304. }
  305. static Boolean MidasConvertStringClass(In,Out)
  306. MidasOperand *In;
  307. MidasOperand *Out;
  308. {
  309.    ListItem *i = MidasFindItemInList(&MidasClassList,In->Value.P);
  310.    if (i == 0) return FALSE;
  311.    Out->Value.P = i->Pointer;
  312.    return TRUE;
  313. }
  314. void MidasDeclareClass(Class)
  315. CoreClassPart *Class;
  316. {
  317.     ListItem *i = MidasFindItemInList(&MidasClassList,Class->class_name);
  318.     if (i==0) 
  319.       {
  320.         i = MidasAddItemToList(&MidasClassList,Class->class_name);
  321.         i->Pointer = Class;
  322.       }
  323. }
  324. static Boolean MidasConvertStringAny(In,Out)
  325. MidasOperand *In;
  326. MidasOperand *Out;
  327. {
  328.    return FALSE;
  329. }
  330. static Boolean MidasConvertIntNumber(In,Out)
  331. MidasOperand *In;
  332. MidasOperand *Out;
  333. {
  334.    *Out = *In;
  335.    return TRUE;
  336. }
  337. static Boolean MidasConvertFloatNumber(In,Out)
  338. MidasOperand *In;
  339. MidasOperand *Out;
  340. {
  341.    *Out = *In;
  342.    return TRUE;
  343. }
  344. static Boolean MidasConvertIntFloat(In,Out)
  345. MidasOperand *In;
  346. MidasOperand *Out;
  347. {
  348.    Out->Value.F = (float) In->Value.I;
  349.    return TRUE;
  350. }
  351. /*
  352.  *
  353.  *  Converting shorts to Ints in a portable way is not trivial 
  354.  *
  355.  */ 
  356. static Boolean MidasConvertIntShort(In,Out)
  357. MidasOperand *In;
  358. MidasOperand *Out;
  359. {
  360.    if (In->Value.I > 32767 || In->Value.I < -32768) return FALSE;
  361.    Out->Value.I = In->Value.I;
  362.    return TRUE;
  363. }
  364. static Boolean MidasConvertShortInt(In,Out)
  365. MidasOperand *In;
  366. MidasOperand *Out;
  367. {
  368.    printf("%x\n",In->Value.I);
  369.    printf("%x\n",In->Value.S);
  370.    Out->Value.I = (int) In->Value.S;
  371.    printf("%x\n",Out->Value.I);
  372.    return TRUE;
  373. }
  374. static Boolean MidasConvertStringNumber(In,Out)
  375. MidasOperand *In;
  376. MidasOperand *Out;
  377. {
  378.    Boolean ok;
  379.  
  380.    ok = MidasConvertStringInt(In,Out);
  381.    if (ok) { Out->Type = MInt;  return ok; }
  382.  
  383.    ok = MidasConvertStringFloat(In,Out);
  384.    if (ok) { Out->Type = MFloat;  return ok; }
  385.    
  386.    return ok;
  387. }
  388. static Boolean MidasConvertStringCursor(In,Out)
  389. MidasOperand *In;
  390. MidasOperand *Out;
  391. {
  392.    int r;
  393.    if      (strcmp(In->Value.P,""     ) == 0) r = 0;
  394.    else if (strcmp(In->Value.P,"watch") == 0) r = XC_watch;
  395.    else if (strcmp(In->Value.P,"trek" ) == 0) r = XC_trek;
  396.    else return False;
  397.  
  398.    Out->Value.I = r; 
  399.    return True;
  400. }
  401. void MidasConvertInit()
  402. {
  403.     ConverterList = NullList;
  404.     MidasClassList = NullList;
  405.  
  406.     MidasDeclareStringConverter("name",       MidasConvertStringName);
  407.     MidasDeclareStringConverter("upname",     MidasConvertStringUpperName);
  408.     MidasDeclareStringConverter("Widget",     MidasConvertStringWidget);
  409.     MidasDeclareStringConverter("list",       MidasConvertStringList);
  410.     MidasDeclareStringConverter("Int",        MidasConvertStringInt);
  411.     MidasDeclareStringConverter("Float",      MidasConvertStringFloat);
  412.     MidasDeclareStringConverter("Icon",       MidasConvertStringIcon);
  413.     MidasDeclareStringConverter("Boolean",    MidasConvertStringBoolean);
  414.     MidasDeclareStringConverter("any",        MidasConvertStringAny);
  415.     MidasDeclareStringConverter("XmString",   MidasConvertStringXmString);
  416.     MidasDeclareStringConverter("MenuWidget", MidasConvertStringWidget);
  417.     MidasDeclareStringConverter("Pixmap",     MidasConvertStringIcon);
  418.     MidasDeclareStringConverter("Cursor",     MidasConvertStringCursor);
  419.     MidasDeclareStringConverter("Class",      MidasConvertStringClass);
  420.  
  421.     MidasDeclareConverter("Boolean","String", MidasConvertBooleanString);
  422.     MidasDeclareConverter("Int","String",     MidasConvertIntString);
  423.     MidasDeclareConverter("Float","String",   MidasConvertFloatString);
  424.     MidasDeclareConverter("String","Number",  MidasConvertStringNumber);
  425.     MidasDeclareConverter("Int","Number",     MidasConvertIntNumber);
  426.     MidasDeclareConverter("Float","Number",   MidasConvertFloatNumber);
  427.     MidasDeclareConverter("Int","Float",      MidasConvertIntFloat);
  428.     MidasDeclareConverter("Int","Short",      MidasConvertIntShort);
  429.     MidasDeclareConverter("Int","HorizontalDimension",MidasConvertIntShort);
  430.     MidasDeclareConverter("Int","VerticalDimension"  ,MidasConvertIntShort);
  431.     MidasDeclareConverter("Int","ShellHorizPos"      ,MidasConvertIntShort);
  432.     MidasDeclareConverter("Int","ShellVertPos"       ,MidasConvertIntShort);
  433.     MidasDeclareConverter("HorizontalDimension","Int",MidasConvertShortInt);
  434.     MidasDeclareConverter("VerticalDimension","Int"  ,MidasConvertShortInt);
  435.     MidasDeclareConverter("HorizontalDimension","Number",MidasConvertShortInt);
  436.     MidasDeclareConverter("VerticalDimension","Number"  ,MidasConvertShortInt);
  437.  
  438.     MidasDeclareFunction("CONVERT(any,name)",MidasConvertForce);
  439.  
  440.     MidasClassInit();
  441. }
  442.